home *** CD-ROM | disk | FTP | other *** search
- #include <iostream.h>
- #include <fstream.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include <unistd.h>
- /*****************************************************************************
- * TextCounter (C++ Version) Version 1.3 *
- * Copyright 1996 Matt Wright mattw@worldwidemart.com *
- * Created 03/14/96 Last Modified 03/28/97 *
- * Matt's Script Archive, Inc. http://www.worldwidemart.com/scripts/ *
- * Perl Version also available at Matt's Script Archive. *
- ******************************************************************************
- * COPYRIGHT NOTICE *
- * Copyright 1996 Matthew M. Wright All Rights Reserved. *
- * *
- * TextCounter may be used and modified free of charge by anyone so long as *
- * this copyright notice and the comments above remain intact. By using this *
- * code you agree to indemnify Matthew M. Wright from any liability that *
- * might arise from it's use. *
- * *
- * Selling the code for this program without prior written consent is *
- * expressly forbidden. In other words, please ask first before you try and *
- * make money off of my program. *
- * *
- * Obtain permission before redistributing this software over the Internet or *
- * in any other medium. In all cases copyright and header must remain intact.*
- *****************************************************************************/
- // Define Variables
-
- // Data Dir is the directory on your server that you wish to store the
- // count files in. Each page that has the counter on it will have it's own
- // file and a lock file will also be created in this directory.
-
- const char data_dir[] = "/path/to/data/";
-
- // Valid-URI allows you to set up the counter to only work under specific
- // directories on your server. Include any of these directories as they
- // appear in a URI, into this array. More information on URI's available in
- // README. num_valid_uri is the number of valid URI's you have in the array.
- // As it is currently set, both valid uri and invalid uri blank, all pages
- // will be allowed.
-
- const int num_valid_uri = 0;
- const char valid_uri[num_valid_uri][128] = { };
-
- // Invalid-URI allows the owner of this script to set up the counter so
- // that certain portions of the web server that may be included in Valid-URI
- // cannot use the program. Set num_invalid_uri to 0 and clear the array if
- // you don't want to use this.
-
- const int num_invalid_uri = 0;
- const char invalid_uri[num_invalid_uri][128] = { };
-
- /****************************************************************************/
- // Set Options
-
- // Show Link allows you to add a link around the counter to point to
- // either instructions explaining to users how to set this up on the system
- // (useful if a system administrator wants to allow anyone to set things up
- // themselves). Setting it to "" will make no link, otherwise put the URL
- // you want linked to the count here.
-
- const char show_link[] = "http://www.worldwidemart.com/scripts/";
-
- // When Auto-Create is enabled, users will be able to auto-create the
- // count on their home pages by simply imbedding the Server Side Includes
- // call. Setting auto_create to 1 enables it, 0 will disable it. Only
- // users in @valid_uri will be allowed to auto create.
-
- const int auto_create = 1;
-
- // Show Date will show the date of when the count began if you set this
- // option to 1. It will appear in yor document as [Count] hits since [Date].
- // Set this to 0 and it will simply return the [Count].
-
- const int show_date = 1;
-
- // Lock Seconds will define the number of seconds the script should sit
- // and wait for the lock file to be gone before it will overwrite it if it
- // is still there. Every now and then a user will interrupt a page, causing
- // the script to halt and leave a lock file in place before the lock file
- // could be removed. This defines how long it waits. Nothing more than
- // 2 or 3 seconds should be needed.
-
- const int lock_sec = 2;
-
- // Padding Size define how many numbers will be shown as your count. For
- // instance, if you want your count to say 00065 and have the zeros padded
- // up to five digits, then set pad_size = 5; If the number goes higher
- // than the pad_size, don't worry, there just won't be any zero's tacked
- // onto the front.
-
- const int pad_size = 5;
-
- /****************************************************************************/
-
- void main() {
- // Declare variables and subroutines
- char *count_page, *count_file, *lock_file;
- char c, date[32];
-
- int i, count, count_page_len;
-
- ifstream count_in;
- ofstream count_out;
-
- int check_uri(char []);
- void error(char [], char []);
- void check_lock(char []);
- void clean_up(char []);
- void create(char []);
- void print_count(int);
-
- // Print Content-type header for browser
- cout << "Content-type: text/html\n\n";
-
- // Get the page location from the DOCUMENT_URI or QUERY_STRING
- // environment variables.
- if (!getenv("DOCUMENT_URI") && !getenv("QUERY_STRING"))
- error("no_uri","X");
-
- // Get the count page's length and store the page name into count_page
- if (strlen(getenv("QUERY_STRING")) > 0)
- {
- count_page_len = strlen(getenv("QUERY_STRING"));
- count_page = new char[count_page_len];
- strcat(count_page,getenv("QUERY_STRING"));
- }
- else
- {
- count_page_len = strlen(getenv("DOCUMENT_URI"));
- count_page = new char[count_page_len];
- strcat(count_page,getenv("DOCUMENT_URI"));
- }
-
- // Check Valid-URI to make sure user can use this program.
- if (!check_uri(count_page))
- error("bad_uri","X");
-
- // Convert '/',':','\' to '_' to avoid directory characters.
- // || count_page[i] == ':' || count_page == '\'
- for (i = 0; i < count_page_len; i++)
- if (count_page[i] == '/')
- count_page[i] = '_';
-
- // Generate the lock filename.
- lock_file = new char[count_page_len + 4];
- strcat(lock_file,data_dir);
- strcat(lock_file,count_page);
- strcat(lock_file,".lck");
-
- // Check to see if file is locked by program already in use.
- check_lock(lock_file);
-
- // Generate the filename for the count page's data file.
- count_file = new char[count_page_len + strlen(data_dir)];
- strcat(count_file,data_dir);
- strcat(count_file,count_page);
-
- // If the file exists, get the date and count out of it. Otherwise, if
- // auto_create is allowed, create a new account. If neither of these are
- // true, return an error.
-
- count_in.open(count_file);
-
- if (!count_in.fail())
- {
-
- // Read in the current count.
- count_in >> count;
-
- // Skip a character and read in next one to begin loop.
- count_in.get(c);
- count_in.get(c);
-
- // Read in the date until the end of file or a new line.
- i = 0;
- while (!count_in.eof() && c != '\n')
- {
- date[i] = c;
- count_in.get(c);
- i++;
- }
- }
- else if (auto_create)
- {
- count_in.close();
- create(count_file);
- }
- else
- {
- count_in.close();
- error("page_not_found","X");
- }
-
- // If the program got this far, close the file, since it hasn't been yet.
- count_in.close();
-
- // Increment Count.
- count++;
-
- // Print the Count, Link and Date depending on what user has specified
- // they wish to print.
-
- if (strlen(show_link) > 0)
- cout << "<a href=\"" << show_link << "\">";
-
- print_count(count);
-
- if (strlen(show_link) > 0)
- cout << "</a>";
-
- if (show_date)
- cout << " hits since " << date;
-
- // Open the count file and write the new count that has been incremented.
-
- count_out.open(count_file);
-
- if (count_out.fail())
- error("could_not_increment",count_file);
- else
- count_out << count << " " << date;
-
- count_out.close();
-
- // Remove Lock File for next time script is run on that HTML page.
- clean_up(lock_file);
- }
-
- int check_uri(char uri[]) {
-
- // Declare variables
- int st = 0, uri_check = 0;
- int valid_uri_len, invalid_uri_len, i, j;
-
- // For each valid URI, check to see if the current uri is included in that
- // valid URI. If so, set the uri check flag to 1 and break out of loop.
- for (i = 0; i < num_valid_uri; i++)
- {
- valid_uri_len = strlen(valid_uri[i]);
- for (j = 0; j < valid_uri_len; j++)
- {
- if (valid_uri[i][j] == uri[st])
- st++;
- else
- st = 0;
-
- if (st == valid_uri_len)
- {
- uri_check = 1;
- break;
- }
- }
- }
-
- // Reset counter st.
- st = 0;
-
- // For each invalid URI, check to see if current uri is included in that
- // invalid URI. If so, set the uri check flag to 0 and break out of loop.
- for (i = 0; i < num_invalid_uri; i++)
- {
- invalid_uri_len = strlen(invalid_uri[i]);
- for (j = 0; j < invalid_uri_len; j++)
- {
- if (invalid_uri[i][j] == uri[st])
- st++;
- else
- st = 0;
-
- if (st == invalid_uri_len)
- {
- uri_check = 0;
- break;
- }
- }
- }
-
- // If both num_valid_uri and num_invalid_uri are set to 0, set the uri
- // check flag to 1, because it is possible QUERY_STRING is being used.
- if (!num_valid_uri && !num_invalid_uri)
- uri_check = 1;
-
- // Return the uri check flag value.
- return uri_check;
- }
-
- void create(char count_file[])
- {
- // Declare variables and subroutines.
- char *date;
- char months[12][10] = { "January", "February", "March", "April", "May",
- "June", "July", "August", "September", "October",
- "November", "December" };
-
- tm *ptm;
- time_t *cur_time;
-
- ofstream count_out;
-
- void error(char [], char []);
- void print_count(int);
-
- // Set up the memory for the time and time time struct.
- cur_time = new time_t;
- ptm = new tm;
-
- // Get the time, then create the struct with time values.
- time(cur_time);
- ptm = localtime(cur_time);
-
- // Write to the file, sending back an error if it fails.
- count_out.open(count_file);
-
- if (count_out.fail())
- error("count_not_created",count_file);
- else
- count_out << 1 << " " << months[ptm->tm_mon] << " " << ptm->tm_mday << ", " << ptm->tm_year + 1900;
-
- count_out.close();
-
- // Print the Count, Link and Date depending on what user has specified
- // they wish to print.
-
- if (strlen(show_link) > 0)
- cout << "<a href=\"" << show_link << "\">";
-
- print_count(1);
-
- if (strlen(show_link) > 0)
- cout << "</a>";
-
- if (show_date)
- cout << " hits since " << months[ptm->tm_mon] << " " << ptm->tm_mday << ", " << ptm->tm_year + 1900;
- ;
-
- exit(0);
- }
-
- void print_count(int count)
- {
- // Declare variables.
- int i, size = 0;
- float count_tmp = count;
-
- // This determines the size of the count integer by divinding by 10 until
- // the result is less than 1.
- while (count_tmp >= 1)
- {
- count_tmp /= 10;
- size++;
- }
-
- // Pad the number with 0's if pad_size is greater than the count size.
- for (i = 0; i < (pad_size - size); i++)
- cout << 0;
-
- // Print the count.
- cout << count;
- }
-
- void error(char error[], char opt_file[])
- {
- // Determine which flag was set and output appropriate error.
- if (strcmp(error,"page_not_found") == 0)
- cout << "[TextCounter Fatal Error: This Page Not Found; Auto-Create Option Disabled]";
- else if (strcmp(error,"no_uri") == 0)
- cout << "[TextCounter Fatal Error: No Document URI or File Flag specified]";
- else if (strcmp(error,"bad_uri") == 0)
- cout << "[TextCounter Fatal Error: This Page Not In Valid URI]";
- else if (strcmp(error,"count_not_created") == 0)
- cout << "[TextCounter Fatal Error: Could Not Write to File " << opt_file << "]";
- else if (strcmp(error,"could_not_increment") == 0)
- cout << "[TextCounter Fatal Error: Could Not Increment Counter File " << opt_file << "]";
-
- exit(0);
- }
-
- void check_lock(char lock_file[])
- {
- // Declare variables.
- int i;
-
- ifstream test_in;
- ofstream test_out;
-
- // For the number of seconds defined in lock_sec...
- for (i = 1; i <= lock_sec; i++)
- {
- // Open the file for reading.
- test_in.open(lock_file);
-
- // If that fails, the lock file doesn't exis. We create the lock file
- // and exit the loop. Otherwise sleep for a second.
- if (test_in.fail())
- {
- test_out.open(lock_file);
- test_out << 0;
- test_out.close();
- break;
- }
- else
- sleep(1);
-
- // Close the file if it is still open.
- test_in.close();
- }
- }
-
- void clean_up(char lock_file[])
- {
- // Remove the lock file.
- unlink(lock_file);
- exit(0);
- }
-